#include "rasterization.h"

rasterization::rasterization(int width, int height):
  width(width),
  height(height)
{
}

void rasterization::drawAPoint(vec3 point, const TGAColor& color){
  TGAImage image(1000,1000,TGAImage::RGB);
  image.set(point.x, point.y, color);
  image.write_tga_file("out/point.tga");
}

void rasterization::drawALine(vec3 p1, vec3 p2, TGAImage& image, const TGAColor& color){
    bool steep = false;
    int x0 = p1.x, y0 = p1.y, x1 = p2.x, y1 = p2.y;
    if(std::abs(x0-x1) < std::abs(y0-y1)){
      std::swap(x0,y0);
      std::swap(x1,y1);
      steep = true;
    }
    if(x0 > x1){
      std::swap(x0,x1);
      std::swap(y0,y1);
    }

    int dx = x1-x0;
    int dy = y1-y0;
    float derror = std::abs(dy)*2;
    float error = 0;
    int y = y0;
    for(int x = x0; x <= x1; x++){
      if(steep){
        image.set(y,x,color);
      }
      else image.set(x,y,color);
      error+=derror;
      if(error > .5){
        y += (y1 > y0 ? 1 : -1);
        error -= dx*2;
      }
    }

}
void rasterization::drawTriangle(Model* model, TGAImage& image, TGAColor color){
    
    for(int i = 0; i < model->nfaces(); i++){
      // std::vector<int> face = model->facet_vrt_(i);
      for(int j = 0; j < 3; j++){
        vec3 v0 = model->vert(i,j)*width/2.+ vec3(width/2., width/2., 0);
        vec3 v1 = model->vert(i,(j+1)%3)*width/2.+vec3(width/2., width/2., 0);
        vec2 p1(v0.x, v0.y),p2(v1.x, v1.y);
        drawALine(p1,p2,image,color);
      }
    }
    image.write_tga_file("out/testOutTriangle.tga");
  }

// 画一个三角面
void rasterization::triangleFace(Model* model, TGAImage& image, TGAColor color){
	vec2 p1,p2,p3;
	for(int i = 0; i < model->nfaces(); i++){
		p1 = model->vert(i,0).xy();
		p2 = model->vert(i,1).xy();
		p3 = model->vert(i,2).xy();
		v_print(p1);
		v_print(p2);
		v_print(p3);
	}
	if(p1.y > p2.y) std::swap(p1,p2);
	if(p1.y > p3.y) std::swap(p1,p3);
	if(p2.y > p3.y) std::swap(p2,p3);
	int total_height = p3.y - p1.y;
	for(int i = 0; i < total_height; i++){
		bool second_half = i > p2.y-p1.y || p2.y==p1.y;
		int segment_height = second_half ? p3.y - p2.y : p2.y-p1.y;
		float alpha = (float)i/total_height;
		float beta = (float)(i - (second_half ? p2.y-p1.y : 0))/segment_height;
		vec2 A = 				p1+(p3-p1)*alpha;
		vec2 B = second_half? p2+(p3-p2)*beta : p1+(p2-p1)*beta;
		if(A.x > B.x) std::swap(A,B);
		for(int j = A.x; j <= B.x; j++){
			image.set(j,p1.x + i,color);
		}
	}
	image.write_tga_file("out/testOutTriangleFace.tga");
}

